/*
 * parser.y
 *
 * Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

%{

#include "element.h"

%}

%union
{
    char *string;
    double number;
    element_t *element;
    list_t list;
}

%token SEMICOLON
%token LEFT_CHEVRON
%token RIGHT_CHEVRON
%token LEFT_PARENTHESIS
%token RIGHT_PARENTHESIS
%token COMMA

%token <string> ATOM
%token <number> NUMBER
%token <string> STRING

%type <list> element_list statement_list
%type <element> element tuple statement

%start toplevel

%%

toplevel        : statement_list
                {
                    // TODO
                }

statement_list  : /* empty */
                {
                    init_list(&$$);
                }
                | statement_list comment
                {
                    /* Skip the comment */
                    $$ = $1;
                }
                | statement_list statement
                {
                    list_append(&$1, &$2->link);
                    $$ = $1;
                }

statement       : LEFT_CHEVRON ATOM element_list RIGHT_CHEVRON
                {
                    $$ = create_statement($2, &$3);
                }

tuple           : LEFT_PARENTHESIS element_list RIGHT_PARENTHESIS
                {
                    $$ = create_tuple(&$2);
                }

element_list    : /* empty */
                {
                    init_list(&$$);
                }
                | element_list comment
                {
                    /* Skip the comment */
                    $$ = $1;
                }
                | element_list element
                {
                    list_append(&$1, &$2->link);
                    $$ = $1;
                }

element         : ATOM
                {
                    $$ = create_atom($1, 0);
                }
                | COMMA ATOM
                {
                    $$ = create_atom($2, 1);
                }
                | STRING
                {
                    $$ = create_string($1);
                }
                | NUMBER
                {
                    $$ = create_number($1);
                }
                | statement
                {
                    $$ = $1;
                }
                | tuple
                {
                    $$ = $1;
                }

comment         : SEMICOLON element { /* Ignored */ }

%%

int yyerror(const char *str)
{
}
